<script setup lang="ts">
import { useI18n } from 'vue-i18n';
import * as yup from 'yup';
import { ApiFinanceMethodComboListV2, ApiFinanceThirdCoinDeposit, ApiPaymentDepositCoinApplication, ApiPaymentDepositCoinCancel, ApiPaymentDepositCoinConfirm, ApiThirdVirtualGetAddr } from '~/apis/index';
import type { virAddreesQrcode } from '~/apis/types';
import { Form } from 'vee-validate';

defineOptions({
  name: 'AppRechargeWithCryptoCurrency',
})
enum ChargeStep {
  CHOOSE_MERCHANT = 1,
  INPUT_AMOUNT,
  TARGET_ACCOUNT
}
enum SheetType {
  CURRENCY = 1,
  MERCHANT
}
const router = useRouter()
const showSheet = ref(false)
const appStore = useAppStore()
const { currentGlobalCurrency, userInfo } = storeToRefs(appStore)
const selectedCurrency = ref()
const selectCurrencyChain = ref()
const selectedAmount = ref()
const selectedMerchant = ref()
const selectedMerchantGroup = ref()
const chargeStep = ref<ChargeStep>(ChargeStep.CHOOSE_MERCHANT)
const { depositCurrencyList } = useCurrencyData()
const sheetType = ref<SheetType>(SheetType.CURRENCY)
const depositFormRef = ref()
const { brandConfig, isOpenFastDeposit, isKYCVerifyOpen } = storeToRefs(useBrandStore())
const { t, locale } = useI18n();
const backDepositInfo: {
  address: string
  amount: string
  memo?: string
  currency_name: string
  id?: string
} = reactive({
  address: '',
  amount: '',
  currency_name: '',
  memo: '',
})
const schema = computed(() => yup.object().shape({
  amount: selectedMerchant.value?.amount_type === 2 ? yup.number()
    .transform((value: string) => (!value ? undefined : Number(value)))
    .required(t('recharge_amount_placeholder'))
    .min(selectedMerchant.value?.amount_min, t('min_amount', {amount: selectedMerchant.value?.amount_min}))
    .max(selectedMerchant.value?.amount_max, t('max_amount', {amount: selectedMerchant.value?.amount_max})) : yup.string().required(t('recharge_amount_select_placeholder'))
}));
const showIds = ref<Array<string>>([])
/** 支付方式&协议V2列表 */
const {
  runAsync: runAsyncPaymentMethodList,
  data: paymentMethodList,
} = useRequest(ApiFinanceMethodComboListV2, {
  onSuccess() {
  },
})
/** 当前的充值优惠 */
const activeDepositPromo = ref('0.00')

// runAsyncPaymentMethodList({currency_id: getCurrencyConfig(currentGlobalCurrency.value).cur})
await application.allSettled([
  runAsyncPaymentMethodList({ currency_id: getCurrencyConfig(currentGlobalCurrency.value).cur }),
])

/** 虚拟币代收付存款地址 */
const {
  runAsync: runAsyncVirDepositAddress,
  loading: virDepositAddressLoading,
} = useRequest(ApiThirdVirtualGetAddr)

/** 虚拟币列表 */
const currencyList = computed(() => {
  if (depositCurrencyList.value.length){
    const res = depositCurrencyList.value.map(a => ({...a, amount: application.formatNumDecimal(a.balance ? a.balance : 0, currencyConfig[a.currency_name].decimal)})).filter(a => application.isVirtualCurrency(a.currency_name))
    selectedCurrency.value = res[0] || {}
    return res
  }
  return []
})

/** 虚拟币存款 */
const { runAsync: runPaymentDepositCoinApplication, loading: paymentDepositCoinInfoLoading, data: rechargeRes } = useRequest(ApiPaymentDepositCoinApplication, {
  onSuccess(data) {
    backDepositInfo.address = data.deposit_coin.wallet_address
    backDepositInfo.currency_name = data.deposit_coin.currency_name
    backDepositInfo.amount = data.amount
    backDepositInfo.id = data.id
    backDepositInfo.memo = data.memo
  },
})

/** 第三方支付存款 */
const {
  runAsync: runFinanceThirdCoinDeposit,
  loading: financeThirdCoinDepositLoading,
  data: thirdRechargeRes
} = useRequest(ApiFinanceThirdCoinDeposit, {
  onSuccess(data) {
    // showNotify()
    backDepositInfo.address = data.address
    backDepositInfo.amount = data.amount
    backDepositInfo.memo = ''
  },
})

const getAmountLimit = computed(() => {
  return (selectedMerchant.value?.amount_min && selectedMerchant.value?.amount_max)
    ? `${selectedMerchant.value?.amount_min}-${selectedMerchant.value?.amount_max}`
    : `${t('recharge_amount_placeholder')}`
})

const {
  run: runPaymentDepositCoinConfirm,
  loading: paymentDepositCoinConfirmLoading,
} = useRequest(ApiPaymentDepositCoinConfirm, {
  onSuccess() {
    // showNotify()
    chargeStep.value = ChargeStep.INPUT_AMOUNT
  },
})
const {
  run: runPaymentDepositCoinCancel,
  loading: paymentDepositCoinCancelLoading,
} = useRequest(ApiPaymentDepositCoinCancel, {
  onSuccess() {
    chargeStep.value = ChargeStep.INPUT_AMOUNT
  },
})

async function depositSubmit() {
  const { values } = depositFormRef.value
  if (selectedMerchant.value?.payment_type === 1) { // 三方支付存款
    await runFinanceThirdCoinDeposit({
      amount: values.amount,
      bank_code: '',
      cid: selectedMerchant.value?.id ?? '',
      mid: selectedMerchantGroup.value?.id,
      currency_id: selectedCurrency.value.currency_id,
      currency_name: selectedCurrency.value.currency_name,
      bankcard_id: selectedCurrency.value?.bankcard_id ?? '',
    })
  }
  else if (selectedMerchant.value?.payment_type === 2) { // 虚拟币存款(公司入款)
    await runPaymentDepositCoinApplication({
      amount: values.amount,
      cid: selectedMerchant.value?.id ?? '',
      currency_id: selectedCurrency.value.currency_id,
      currency_name: selectedCurrency.value.currency_name,
      mid: selectedMerchantGroup.value?.id,
      bankcard_id: selectedMerchant.value?.bankcard_id ?? '',
    })
  }
  chargeStep.value = ChargeStep.TARGET_ACCOUNT
}

const currencyChainList = computed(() => {
  if (!selectedCurrency.value)
    return []
  let _pay = []
  if (paymentMethodList.value?.method && paymentMethodList.value.method.length > 0) {
    const showQrcodeFast = isOpenFastDeposit.value ? true : (paymentMethodList.value?.method.filter(item => item.merchants.filter(child => child.payment_type === 3).length > 0).length > 0 && brandConfig.value?.base?.fast === 1)
    if (showQrcodeFast) {
      const methodList = paymentMethodList.value?.method.filter(item => item.merchants.filter(child => child.payment_type === 3).length > 0)
      const _methodList: string[] = []
      let _contractList: any[] = []
      if (methodList) {
        methodList.forEach((item) => {
          _methodList.push(item.contract_id)
        })
      }
      _contractList = paymentMethodList.value?.contract?.filter(a => a.currency_id === selectedCurrency.value.currency_id) as any[] || []
      return _pay = _contractList[0]?.contract_list.filter((contract: { value: string }) => _methodList.includes(contract.value))
    }
    else {
      _pay = paymentMethodList.value?.contract?.filter(a => a.currency_id === selectedCurrency.value.currency_id) ?? []
      return _pay[0]?.contract_list
    }
  }
})



async function selectCurrency (item: availableCurrency & BaseOption, type: 1 | 2, isShowSheet = true) {
    chargeStep.value = ChargeStep.CHOOSE_MERCHANT
    selectedMerchant.value = ''
    if(type === 1){
      selectedCurrency.value = item
      selectCurrencyChain.value = currencyChainList.value?.[0]
      setTimeout(() => {
        showSheet.value = isShowSheet
        sheetType.value = SheetType.MERCHANT
      }, 85)
    }else {
        activeDepositPromo.value = '0.00'
        selectedAmount.value = ''
        setTimeout(() => {
          showSheet.value = false
        }, 50)
      selectCurrencyChain.value = item
      await runAsyncPaymentMethodList({ currency_id: selectedCurrency.value.currency_id, contract_id: selectCurrencyChain.value?.value })
      updateVirAddress()
    }
}

const curDepositPromo = computed(() => paymentMethodList.value?.method.find(item => item.id === selectedMerchant.value?.method_id)?.deposit_promo)

/** 充值优惠列表 */
const depositPromoArray = computed(() => {
  if (curDepositPromo.value && curDepositPromo.value.length > 0) {
    return curDepositPromo.value.map((i) => {
      return {
        ...i,
        label: i.max,
        value: i.max,
        bonus: i.bonus_max,
      }
    })
  }
  else {
    return []
  }
})

function promoAmount(amount: number) {
  const bonusMax = depositPromoArray.value.length > 0 ? Number.parseFloat(depositPromoArray.value?.[depositPromoArray.value.length - 1].bonus_max) : 0
  const _amount = amount as number
  if (_amount > 0 && depositPromoArray.value.length > 0) {
    if (_amount >= Number.parseFloat(depositPromoArray.value?.[depositPromoArray.value.length - 1].min)) {
      if (depositPromoArray.value.length > 0 && bonusMax > 0) {
        const ratio = Number.parseFloat(depositPromoArray.value?.[0].ratio)
        return ratio * _amount > bonusMax ? bonusMax : ratio * _amount
      }
      else if (depositPromoArray.value.length > 0 && bonusMax === 0) {
        const ratio = Number.parseFloat(depositPromoArray.value?.[0].ratio)
        return ratio * _amount
      }
      else {
        return 0.00
      }
    }
    else {
      return 0.00
    }
  }
  else {
    return 0.00
  }
}

watch(selectedAmount, (a: string) => {
  if (Number.isNaN(Number(a)))
    return
  activeDepositPromo.value = application.formatNumDecimal(promoAmount(Number.parseFloat(a)).toFixed(8), currencyConfig[selectedCurrency.value.currency_name as EnumCurrencyKey].decimal)
})

const merchants = computed(() => {
  if (paymentMethodList.value?.method?.length && selectCurrencyChain.value) {
    return paymentMethodList.value.method.map((a) => {
      return {
        ...a,
        merchants: showIds.value.includes(a.id) ? a.merchants : a.merchants.length > 10 ? a.merchants.slice(0, 3) : a.merchants.slice(0, 2),
      }
    })
  }
  return []
})

const strToArray = function (amount: string) {
  const temp = amount.split(',').filter(str => str.trim() !== '')
  return temp.map((i) => {
    return {
      label: i,
      value: i,
    }
  })
}

/** 常用金额 */
const amountList = computed(() => {
  return strToArray(selectedMerchant.value?.often_amount ?? '')
})

/** 是否直接显示虚拟币代收付二维码 */
const showQrcode = computed(() => {
  return isOpenFastDeposit.value ? true : paymentMethodList.value?.method.length === 1 && paymentMethodList.value?.method[0].merchants.length === 1 && paymentMethodList.value?.method[0].merchants[0].payment_type === 3
})

const showQrcodeFast = computed(() => {
  if (isOpenFastDeposit.value)
    return true
  if (paymentMethodList.value?.method && paymentMethodList.value.method.length > 0)
    return paymentMethodList.value?.method.filter(item => item.merchants.filter(child => child.payment_type === 3).length > 0).length > 0 && brandConfig.value?.base?.fast === 1
})

/** 存款地址 */
const virAddressQrCodeData = ref<virAddreesQrcode>({
  virDepositAddrees: '',
  virDepositRatio: '',
  virDepositMin: '',
  currency: '',
})

function selectMerchant (val: Merchant, merchantGroup: MerchantGroup) {
  selectedMerchantGroup.value = merchantGroup
  chargeStep.value = ChargeStep.INPUT_AMOUNT
  selectedMerchant.value = val
}

watch(() => currencyList, () => {
  currencyList.value?.length && selectCurrency(currencyList.value[0], SheetType.CURRENCY, false)
}, { immediate: true })

watch(() => currencyChainList, () => {
  currencyChainList.value?.length && selectCurrency(currencyChainList.value[0], SheetType.MERCHANT, false)
}, { immediate: true })

/** 更新二维码的相关数据 */
function updateVirAddress() {
  const virDepositList = paymentMethodList.value?.method.filter(item => item.merchants.filter(child => child.payment_type === 3).length > 0)
  if (virDepositList && virDepositList.length > 0) {
    const merchants = virDepositList[0].merchants.filter(item => item.payment_type === 3)
    virAddressQrCodeData.value.virDepositRatio = virDepositList[0].deposit_promo[0] === undefined ? '' : virDepositList[0].deposit_promo[0].ratio
    virAddressQrCodeData.value.virDepositMin = virDepositList[0].deposit_promo[0] === undefined ? '' : virDepositList[0].deposit_promo[0].min
    virAddressQrCodeData.value.currency = selectedCurrency.value.currency_name
    runAsyncVirDepositAddress({ id: merchants[0].id, mid: virDepositList[0].id, currency_id: selectedCurrency.value.currency_id }).then((data) => {
      virAddressQrCodeData.value.virDepositAddrees = data || ''
    })
  }
}
</script>

<template>
  <AppBaseCard>
    <div class="flex gap-[.6875rem] mb-[1rem]">
      <BaseInput required :label="t('recharge_currency')" name="currency_name" :modelValue="selectedCurrency?.currency_name"  @click="showSheet = true; sheetType = SheetType.CURRENCY" type="select">
        <template v-slot:left-icon>
          <AppCurrencyIcon class="size-[1.25rem]" :currency-type="getCurrencyConfigByCode(selectedCurrency.currency_id)?.['name']"/>
        </template>
      </BaseInput>
      <BaseInput required :label="t('recharge_choose_chain')" name="label" :modelValue="selectCurrencyChain?.label"  @click="showSheet = true; sheetType = SheetType.MERCHANT" type="select">
      </BaseInput>
      <BaseSheet
        v-model="showSheet"
        :title="sheetType === SheetType.CURRENCY ? t('recharge_choose_currency') : t('recharge_choose_chain')"
        :showSearch="sheetType === SheetType.CURRENCY"
        :filterKey="sheetType === SheetType.CURRENCY ? 'currency_name' : 'label'"
        :items="sheetType === SheetType.CURRENCY ? currencyList : currencyChainList"
      >
        <template #default="{ item }: { item?: availableCurrency & BaseOption & {amount: number} }">
          <li
            class="mx-[0.875rem] h-[2.5rem] px-[0.5rem] rounded-[0.375rem] flex items-center justify-between"
            :class="[sheetType === SheetType.CURRENCY ? 
            (item?.currency_id === selectedCurrency.currency_id && 'bg-bg-black-4'):
            (item?.value === selectCurrencyChain.value && 'bg-bg-black-4')]"
            @click="selectCurrency(item!, sheetType)"
          >
            <div class="flex items-center gap-[.1875rem]">
              <!-- 货币图标 -->
              <AppCurrencyIcon class="size-[1.25rem]" v-if="sheetType === SheetType.CURRENCY"
                :currency-type="getCurrencyConfigByCode(item!.currency_id)?.['name']" />
              <span class="font-medium text-text-white-1 text-[1rem] ml-[.5rem]">{{ item?.currency_name || item?.label }}</span>
            </div>
            <span class="text-text-white-1 text-[1rem]" v-if="sheetType === SheetType.CURRENCY">{{ item?.amount }}</span>
            <div class="size-[1rem] border-[.1875rem] border-brand rounded-[50%]"
              v-if="sheetType === SheetType.MERCHANT && item?.value === selectCurrencyChain.value"></div>
          </li>
        </template>
      </BaseSheet>
    </div>
    <template v-if="chargeStep === ChargeStep.INPUT_AMOUNT">
      <Form :validation-schema="schema" @submit="depositSubmit" ref="depositFormRef">
        <BaseInput required :label="t('recharge_amount')" name="amount" :placeholder="getAmountLimit" :modelValue="selectedAmount">
          <template v-slot:right-icon>
            <div class="text-brand text-[1rem] font-[700]">赠送+{{ activeDepositPromo }}</div>
          </template>
        </BaseInput>
        <div class="grid grid-cols-3 gap-y-[.375rem] gap-x-[.4375rem] mt-[.75rem]">
          <div v-for="amount in amountList" :key="amount.value" class="bg-bg-black-10 rounded-[.25rem] h-[2.625rem] flex justify-center items-center font-[600] text-[1rem]" :class="[selectedAmount === amount.value && 'border border-brand']" @click="selectedAmount = amount.value">{{ amount.value }}</div>
        </div>
        <BaseButton class="w-full h-[2.5rem] mt-[1rem]" html-type="submit" :loading="financeThirdCoinDepositLoading || paymentDepositCoinInfoLoading">
          <span class="text-text-black-10 text-[.75rem] mr-[.25rem]">{{t('recharge_confirm_pay')}}</span>
          <BaseIcon name="uni-share" class="text-text-black-10" />
        </BaseButton>
      </Form>
    </template>
    <template v-if="chargeStep === ChargeStep.CHOOSE_MERCHANT || chargeStep === ChargeStep.TARGET_ACCOUNT">
      <div v-if="showQrcode || showQrcodeFast || chargeStep === ChargeStep.TARGET_ACCOUNT">
        <div class="flex gap-[1rem] my-[1.125rem]">
          <div class="size-[7.75rem] rounded-[.25rem] relative overflow-hidden shrink-0 bg-white p-[.25rem] ">
            <BaseQrcode :url="virAddressQrCodeData.virDepositAddrees" :size="116"/>
            <div class="absolute w-full h-full rounded-[.25rem] bg-[rgba(0, 0, 0, 0.7)] flex justify-center items-center text-[.75rem] text-text-white-1">{{ t('recharge_address_invalid') }}</div>
          </div>
          <div class="flex-1 shrink-1">
            <div class="text-text-white-2 text-[.75rem] font-[600] mb-[.375rem] w-full">{{t('recharge_address')}}</div>
            <div class="w-full bg-bg-black-2 py-[.5rem] h-[2.875rem] pl-[.5625rem] pr-[1.125rem] text-[.625rem] rounded-[.5rem] mb-[.875rem] break-all whitespace-pre-wrap">
              {{virAddressQrCodeData.virDepositAddrees}}
            </div>
            <BaseButton @click="application.copy(virAddressQrCodeData.virDepositAddrees ?? '', t)" class="w-full h-[2.5rem] mt-[1rem] text-text-black-10 text-[.75rem]" type="secondary">
              <BaseIcon name="uni-copy" class="text-text-black-10 mr-[.25rem]" />
              {{t('recharge_copy_address')}}
            </BaseButton>
          </div>
        </div>
        <AppRechargeTip v-if="chargeStep !== ChargeStep.TARGET_ACCOUNT" className="!py-[.5rem]" :text="t('recharge_crypto_tip', {text1: virAddressQrCodeData.virDepositMin, text2: selectedCurrency.currency_name, text3: virAddressQrCodeData.virDepositRatio})"/>
        <BaseInput required :modelValue="selectedMerchant.value?.payment_type === 1 ? thirdRechargeRes?.amount : rechargeRes?.amount" name="amount" showCopy disabled v-if="chargeStep === ChargeStep.TARGET_ACCOUNT" :label="t('recharge_amount')">
          <template v-slot:left-icon>
            <AppCurrencyIcon class="size-[1.25rem]" :currency-type="getCurrencyConfigByCode(selectedCurrency.currency_id)?.['name']"/>
          </template>
        </BaseInput>
        <AppRechargeTip v-if="chargeStep === ChargeStep.TARGET_ACCOUNT" :text="t('recharge_check_tip')"/>
        <div class="flex gap-[.625rem]" v-if="chargeStep === ChargeStep.TARGET_ACCOUNT">
          <BaseButton :loading="paymentDepositCoinCancelLoading" @click="runPaymentDepositCoinCancel({ id: backDepositInfo.id ?? '' })" class="w-full h-[2.5rem] mt-[1rem] text-text-black-10 text-[.75rem]" type="secondary">
            {{t('recharge_cancel')}}
          </BaseButton>
          <BaseButton :loading="paymentDepositCoinConfirmLoading" @click="runPaymentDepositCoinConfirm({ id: backDepositInfo.id ?? '' })" class="w-full h-[2.5rem] mt-[1rem] text-text-black-10 text-[.75rem]">
            {{t('recharge_paid')}}
          </BaseButton>
        </div>
      </div>
      <BasePaymentMerchant :merchantGroups="merchants" v-else @change="selectMerchant" :isCrypto="true"></BasePaymentMerchant>
      <AppRechargeTip v-if="chargeStep !== ChargeStep.TARGET_ACCOUNT">
          <span class="text-function-green">{{t('common_on')}}</span>
          <span class="underline mr-[.5rem] text-function-green" @click="router.push('setting/two-factor-auth')">2FA</span>
          <span class="text-text-white-2">{{ t('recharge_2fa_tip') }}</span>
        </AppRechargeTip>
    </template>
  </AppBaseCard>
</template>
